package backend

import (
	"context"
	"gitee.com/go-caipu-team/go-caipu-plugin-sdk/genproto/pluginv2"
	"net/http"
)

// resourceSDKAdapter adapter between low level plugin protocol and SDK interfaces.
type resourceSDKAdapter struct {
	callResourceHandler CallResourceHandler
	executeHandler      CallResourceHandler
}

func newResourceSDKAdapter(handler CallResourceHandler) *resourceSDKAdapter {
	return &resourceSDKAdapter{
		callResourceHandler: handler,
		executeHandler:      handler,
	}
}

type callResourceResponseSenderFunc func(resp *CallResourceResponse) error

func (fn callResourceResponseSenderFunc) Send(resp *CallResourceResponse) error {
	return fn(resp)
}
func (a *resourceSDKAdapter) CallResource(protoReq *pluginv2.CallResourceRequest, protoSrv pluginv2.Resource_CallResourceServer) error {
	if a.callResourceHandler == nil {
		return protoSrv.Send(&pluginv2.CallResourceResponse{
			Code: http.StatusNotImplemented,
		})
	}

	fn := callResourceResponseSenderFunc(func(resp *CallResourceResponse) error {
		return protoSrv.Send(ToProto().CallResourceResponse(resp))
	})

	ctx := protoSrv.Context()
	ctx = propagateTenantIDIfPresent(ctx)
	parsedReq := FromProto().CallResourceRequest(protoReq)
	ctx = withHeaderMiddleware(ctx, parsedReq.GetHTTPHeaders())
	return a.callResourceHandler.CallResource(ctx, parsedReq, fn)
}
func (a *resourceSDKAdapter) Execute(ctx context.Context, req *pluginv2.ExecuteRequest) (*pluginv2.ExecuteResponse, error) {
	ctx = propagateTenantIDIfPresent(ctx)
	parsedRequest := FromProto().ExecuteRequest(req)
	ctx = withHeaderMiddleware(ctx, parsedRequest.GetHTTPHeaders())
	resp, err := a.executeHandler.Execute(ctx, parsedRequest)
	if err != nil {
		return nil, err
	}
	return ToProto().ExecuteResponse(resp), nil
}
